from tkinter import messagebox
from project_info import *
import tkinter as tk
import os
from tkinter import *
import textwrap
import re

class Tools():
    #初始化：容器、列定义、排序后的回调
    def __init__(self):
        self.project = ProjectInfo().conf()

    # 使用字符串乘法生成重复字符的字符串
    def gen_string(self, char, length):
        result = char * length 
        return result
   
    def wrap_text(self, s, width):
        # 使用textwrap.wrap进行换行处理，返回新的字符串
        # print("wrap_text", s, width)
        ret = textwrap.wrap(s, width=int(width))
        return "\n".join(ret)
    
    def wrap_text_gbk(self, s, width):
        # 换行处理，一个汉字占2个宽度，返回新的字符串。要求宽度 >= 2
        s = str(s)
        if len(s) == 0 or width < 2: return ''

        _len    = len(s)
        _start  = 0
        ret = []
        while 1:
            str_tmp = self.sub_str(s, _start, width)
            ret.append(str_tmp)
            _start = _start + len(str_tmp)
            if _start >= _len: break

        return "\n".join(ret)
    
    def str_len(self, s):
        """取字符串长度，一个汉字、全角符号占2个宽度
        使用正则表达式匹配汉字，并将其替换为两个占位符
        """
        s = re.sub(r'[\u4e00-\u9fff]', 'xx', str(s))  # 这里的'xx'是占位符，可以根据需要调整
        s = re.sub(r'[\uFF00-\uFFEF]', 'xx', s)       # 全角符号
    
        return len(s)
    
    def sub_str(self, s, start, width):
        # 字符串截取，一个汉字占2个宽度，要保证截取的内容刚才等于或小于width，且不能从汉字中间截断
        if len(s) == 0 or start < 0 or width < 2: return ''

        if len(s) > start + width:
            str_tmp = s[start : start + width]
        else:
            str_tmp = s[start : ]

        # print(f"sub_str,str_tmp:{str_tmp}")
        while 1:
            if self.str_len(str_tmp) <= width:
                return str_tmp
            
            str_tmp = str_tmp[0 : len(str_tmp) - 1]    # 删除最右的字符
            # print(f"sub_str,str_tmp:{str_tmp}")

    def msg(self, message, type='info', title=''):
        """
        显示消息框
        message (string)    显示文本
        type    (string)    类型:info,warning,error,question,okcancel,retrycancel,yesno,yesnocancel
        title   (string)    窗口标题
        """
        if title == None or title == '': title = self.project['name']

        if type == 'info':
            messagebox.showinfo(title, message)
        if type == 'warning':
            messagebox.showwarning(title, message)
        if type == 'error':
            messagebox.showerror(title, message)

        if type == 'question':
            return messagebox.askquestion(title, message)
        if type == 'okcancel':
            return messagebox.askokcancel(title, message)
        if type == 'retrycancel':
            return messagebox.askretrycancel(title, message)
        if type == 'yesno':
            return messagebox.askyesno(title, message)
        if type == 'yesnocancel':
            return messagebox.askyesnocancel(title, message)
            
    def is_num(self, exp):
        """判断字符串是否数值
        """
        try:
            float(exp)
            return True
        except ValueError:
            return False
        
    def in_list(self, list_data, element):
        """判断项目是否在列表中
        """
        if element in list_data:
            return True
        else:
            return False
        
    def file_exist(self, filename, give_msg = True):
        """检查文件是否存在，成功返回True
        """
        if os.path.exists(filename):
            return True
        else:
            print(f"配置文件【{filename}】不存在")
            if give_msg: self.msg(f"系统所需文件【{filename}】不存在！", 'warning')
            return False

    def get_geometry(self, win, w, h):
        """计算窗口居中位置，返回字符串，用于“geometry”方法。参数：窗口、宽、高
        """
        screen_width = win.winfo_screenwidth()
        screen_height = win.winfo_screenheight()
        if w > screen_width:    w = screen_width
        if h > screen_height:   h = screen_height

        x = int((screen_width - w) / 2)
        y = int((screen_height - h) / 2)

        return f"{w}x{h}+{x}+{y}"